package pku.edu.cn.context.service;

import java.util.HashMap;
import java.util.List;

import org.alljoyn.bus.BusAttachment;
import org.alljoyn.bus.BusException;
import org.alljoyn.bus.BusListener;
import org.alljoyn.bus.SessionPortListener;
import org.alljoyn.bus.BusObject;
import org.alljoyn.bus.Mutable;
import org.alljoyn.bus.SessionOpts;
import org.alljoyn.bus.Status;

import android.app.Activity;
import android.database.Cursor;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.provider.ContactsContract;
import android.text.format.Time;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

/*
 * This is a simple AllJoyn service that will provide access to context
 * information on the phone.
 */
public class ContextService extends Activity {
    static {
        System.loadLibrary("alljoyn_java");
    }

    private static final String TAG = "ContextsService";
    
    private static final int MESSAGE_ACTION = 1;
    private static final int MESSAGE_POST_TOAST = 2;
    
    private BusHandler mBusHandler;
    
    public Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) { 
            case MESSAGE_ACTION: {
                mListViewArrayAdapter.add((String) msg.obj); 
                break;
            }
            case MESSAGE_POST_TOAST:
                Toast.makeText(getApplicationContext(), (String) msg.obj, Toast.LENGTH_LONG).show();
                break;
            default: 
                break;
            }
        }
    };
    
    private ArrayAdapter<String> mListViewArrayAdapter;
    private Menu menu;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mListViewArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.test_list_item);
        ListView lv = (ListView) findViewById(R.id.ListView);
        lv.setAdapter(mListViewArrayAdapter);
        
        /*
         * Send an empty message to list to make it clear where the start of
         * the list is. 
         */
        Message msg = mHandler.obtainMessage(MESSAGE_ACTION, "");
        mHandler.sendMessage(msg);
        
        HandlerThread busThread = new HandlerThread("BusHandler");
        busThread.start();
        mBusHandler = new BusHandler(busThread.getLooper());
        mBusHandler.sendEmptyMessage(BusHandler.CONNECT); 
    }
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.mainmenu, menu);
        this.menu = menu;
        return true;
    }
    
    @Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case R.id.quit:
	    	finish();
	        return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        
        mBusHandler.sendEmptyMessage(BusHandler.DISCONNECT);
    }
    
    /**
     * Local implementation of the AwarenessInterface
     */
    private class AllJoynContextService implements AwarenessInterface, BusObject {

        /*
         * Given a name find the context information for that name.
         * return the filled in context container.
         */
        public Context getContext(String type, int id) throws BusException {
            Context context = new Context();
            context.id = id;
            context.type = "wifi";
            
            
            WifiManager wifi_service = (WifiManager)getSystemService(WIFI_SERVICE); 
            WifiInfo wifiInfo = wifi_service.getConnectionInfo(); 

            context.data.name = wifiInfo.getSSID();
            context.data.content= String.format("Power is :%d",wifiInfo.getRssi());
            
            List<WifiConfiguration> wf  = wifi_service.getConfiguredNetworks();
            StringBuffer sb = new StringBuffer();  
            for(int i=0;i<wf.size();i++){
            	sb.append(wf.get(i).SSID);
            }
            context.data.detail = sb.toString();
            
            
            context.data.detail = String.format("");
            
            Time t=new Time("GMT+8"); 
            t.setToNow();
            context.time = ""+t.hour+t.minute+t.second;

            String action = String.format("Information about %s sent to Client", context.type);
            Message msg = mHandler.obtainMessage(MESSAGE_ACTION, action);
            mHandler.sendMessage(msg);
            Log.i(TAG, action);
            
            return context;
        }

		@Override
		public NameId[] getAllContextNames() throws BusException {
			 Log.i(TAG, String.format("Client requested a list of contacts"));
	            NameId[] result;
	            int count=1;
	            result = new NameId[count];
	            result[0] = new NameId();
	            result[0].displayName = "wifi";
	            result[0].userId = 0;
	            String action = String.format("Sending list of %d contexts to Client", count);
	            Message msg = mHandler.obtainMessage(MESSAGE_ACTION, action);
	            mHandler.sendMessage(msg);
	            
	            Log.i(TAG, action);
	            return result;
		}

    }  
    
    class BusHandler extends Handler {
        private static final String SERVICE_NAME = "org.alljoyn.bus.awareness";
        private static final short CONTACT_PORT = 42;
        
        BusAttachment mBus;
        
        private AllJoynContextService mService;

        /* These are the messages sent to the BusHandler from the UI. */
        public static final int CONNECT = 1;
        public static final int DISCONNECT = 2;

        public BusHandler(Looper looper) {
            super(looper);
            
            mService = new AllJoynContextService();
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case CONNECT: {
            	org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());
                mBus = new BusAttachment(getPackageName(), BusAttachment.RemoteMessage.Receive);
                
                mBus.registerBusListener(new BusListener());

                Status status = mBus.registerBusObject(mService, "/awareness");
                logStatus("BusAttachment.registerBusObject()", status);
                              
                status = mBus.connect();
                logStatus("BusAttachment.connect()", status);
                
                Mutable.ShortValue contextPort = new Mutable.ShortValue(CONTACT_PORT);

                SessionOpts sessionOpts = new SessionOpts();
                sessionOpts.traffic = SessionOpts.TRAFFIC_MESSAGES;
                sessionOpts.isMultipoint = false;
                sessionOpts.proximity = SessionOpts.PROXIMITY_ANY;
                sessionOpts.transports = SessionOpts.TRANSPORT_ANY;

                status = mBus.bindSessionPort(contextPort, sessionOpts, new SessionPortListener() {
                	@Override
                	public boolean acceptSessionJoiner(short sessionPort, String joiner, SessionOpts sessionOpts) {
                		if (sessionPort == CONTACT_PORT) {
                			return true;
                        } else {
                        	return false;
                        }
                    }
                });
                logStatus(String.format("BusAttachment.bindSessionPort(%d, %s)",
                    contextPort.value, sessionOpts.toString()), status);

                if (status != Status.OK) {
                    finish();
                    return;
                }
 
                status = mBus.requestName(SERVICE_NAME, BusAttachment.ALLJOYN_REQUESTNAME_FLAG_DO_NOT_QUEUE);
                logStatus("BusAttachment.requestName()", status);
                
                status = mBus.advertiseName(SERVICE_NAME, SessionOpts.TRANSPORT_ANY);
                logStatus(String.format("BusAttachment.advertiseName(%s)", SERVICE_NAME), status);
                break;
            }
            case DISCONNECT: {
                mBus.unregisterBusObject(mService);
                mBus.disconnect();
                mBusHandler.getLooper().quit();
                break;
            }
            default:
                break;
            
            }
        }
    }
    
    private void logStatus(String msg, Status status) {
        String log = String.format("%s: %s", msg, status);
        if (status == Status.OK) {
            Log.i(TAG, log);
        } else {
            Message toastMsg = mHandler.obtainMessage(MESSAGE_POST_TOAST, log);
            mHandler.sendMessage(toastMsg);
            Log.e(TAG, log);
        }
    }
}